package com.example.testplatform.config;

import com.example.testplatform.common.Constants;
import com.example.testplatform.entity.Menu;
import com.example.testplatform.entity.Role;
import com.example.testplatform.entity.RoleMenu;
import com.example.testplatform.entity.User;
import com.example.testplatform.service.MenuService;
import com.example.testplatform.service.RoleMenuService;
import com.example.testplatform.service.RoleService;
import com.example.testplatform.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 系统初始化组件
 * 在系统启动时执行必要的初始化操作
 */
@Component
public class SystemInitializer implements ApplicationRunner {

    private static final Logger logger = LoggerFactory.getLogger(SystemInitializer.class);

    @Autowired
    private UserService userService;
    
    @Autowired
    private RoleService roleService;
    
    @Autowired
    private MenuService menuService;
    
    @Autowired
    private RoleMenuService roleMenuService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    @Transactional
    public void run(ApplicationArguments args) {        
        logger.info("开始执行系统初始化操作...");
        
        // 初始化角色
        initRoles();
        
        // 初始化菜单
        initMenus();
        
        // 初始化管理员用户
        initAdminUser();
        
        // 为管理员角色分配所有菜单权限
        assignAllMenusToAdminRole();
        
        logger.info("系统初始化操作完成。");
    }

    /**
     * 初始化角色
     * 如果系统中不存在预设角色，则创建这些角色
     */
    private void initRoles() {
        List<Role> rolesToCreate = new ArrayList<>();
        
        // 检查并创建管理员角色
        if (!roleService.checkRoleCodeExists(Constants.Role.ADMIN, null)) {
            Role adminRole = new Role();
            adminRole.setRoleName("系统管理员");
            adminRole.setRoleCode(Constants.Role.ADMIN);
            adminRole.setDescription("系统管理员，拥有最高权限");
            adminRole.setStatus(1);
            adminRole.setCreateTime(LocalDateTime.now());
            adminRole.setUpdateTime(LocalDateTime.now());
            rolesToCreate.add(adminRole);
        }
        
        // 检查并创建产品经理角色
        if (!roleService.checkRoleCodeExists(Constants.Role.PRODUCT_MANAGER, null)) {
            Role productManagerRole = new Role();
            productManagerRole.setRoleName("产品经理");
            productManagerRole.setRoleCode(Constants.Role.PRODUCT_MANAGER);
            productManagerRole.setDescription("负责产品管理和测试申请");
            productManagerRole.setStatus(1);
            productManagerRole.setCreateTime(LocalDateTime.now());
            productManagerRole.setUpdateTime(LocalDateTime.now());
            rolesToCreate.add(productManagerRole);
        }
        
        // 检查并创建测试经理角色
        if (!roleService.checkRoleCodeExists(Constants.Role.TEST_MANAGER, null)) {
            Role testManagerRole = new Role();
            testManagerRole.setRoleName("测试经理");
            testManagerRole.setRoleCode(Constants.Role.TEST_MANAGER);
            testManagerRole.setDescription("负责测试管理和团队管理");
            testManagerRole.setStatus(1);
            testManagerRole.setCreateTime(LocalDateTime.now());
            testManagerRole.setUpdateTime(LocalDateTime.now());
            rolesToCreate.add(testManagerRole);
        }
        
        // 检查并创建测试人员角色
        if (!roleService.checkRoleCodeExists(Constants.Role.TESTER, null)) {
            Role testerRole = new Role();
            testerRole.setRoleName("测试人员");
            testerRole.setRoleCode(Constants.Role.TESTER);
            testerRole.setDescription("负责执行测试任务和提交缺陷");
            testerRole.setStatus(1);
            testerRole.setCreateTime(LocalDateTime.now());
            testerRole.setUpdateTime(LocalDateTime.now());
            rolesToCreate.add(testerRole);
        }
        
        // 批量创建角色
        if (!rolesToCreate.isEmpty()) {
            for (Role role : rolesToCreate) {
                roleService.save(role);
                logger.info("成功创建角色: {}", role.getRoleName());
            }
        } else {
            logger.info("所有预设角色已存在，无需初始化");
        }
    }
    
    /**
     * 初始化菜单
     * 如果系统中不存在预设菜单，则创建这些菜单
     */
    private void initMenus() {
        // 查询是否已经存在菜单
        List<Menu> existingMenus = menuService.getAllMenus();
        if (!existingMenus.isEmpty()) {
            logger.info("系统已存在菜单，无需初始化");
            return;
        }
        
        List<Menu> menusToCreate = new ArrayList<>();
        
        // 系统管理主菜单
        Menu systemMenu = new Menu();
        systemMenu.setMenuName("系统管理");
        systemMenu.setParentId(0L);
        systemMenu.setPath("/system");
        systemMenu.setComponent("Layout");
        systemMenu.setIcon("system");
        systemMenu.setSort(1);
        systemMenu.setStatus(1);
        systemMenu.setCreateTime(LocalDateTime.now());
        systemMenu.setUpdateTime(LocalDateTime.now());
        menusToCreate.add(systemMenu);
        
        // 用户管理菜单
        Menu userMenu = new Menu();
        userMenu.setMenuName("用户管理");
        userMenu.setParentId(1L);  // 假设系统管理菜单ID为1
        userMenu.setPath("/system/users");
        userMenu.setComponent("system/user/index");
        userMenu.setIcon("user");
        userMenu.setSort(1);
        userMenu.setStatus(1);
        userMenu.setCreateTime(LocalDateTime.now());
        userMenu.setUpdateTime(LocalDateTime.now());
        menusToCreate.add(userMenu);
        
        // 角色管理菜单
        Menu roleMenu = new Menu();
        roleMenu.setMenuName("角色管理");
        roleMenu.setParentId(1L);  // 假设系统管理菜单ID为1
        roleMenu.setPath("/system/roles");
        roleMenu.setComponent("system/role/index");
        roleMenu.setIcon("role");
        roleMenu.setSort(2);
        roleMenu.setStatus(1);
        roleMenu.setCreateTime(LocalDateTime.now());
        roleMenu.setUpdateTime(LocalDateTime.now());
        menusToCreate.add(roleMenu);
        
        // 菜单管理菜单
        Menu menuMenu = new Menu();
        menuMenu.setMenuName("菜单管理");
        menuMenu.setParentId(1L);  // 假设系统管理菜单ID为1
        menuMenu.setPath("/system/menus");
        menuMenu.setComponent("system/menu/index");
        menuMenu.setIcon("menu");
        menuMenu.setSort(3);
        menuMenu.setStatus(1);
        menuMenu.setCreateTime(LocalDateTime.now());
        menuMenu.setUpdateTime(LocalDateTime.now());
        menusToCreate.add(menuMenu);
        
        // 批量创建菜单
        if (!menusToCreate.isEmpty()) {
            for (Menu menu : menusToCreate) {
                menuService.createMenu(menu);
                logger.info("成功创建菜单: {}", menu.getMenuName());
            }
        }
    }

    /**
     * 初始化管理员用户
     * 如果系统中不存在admin用户，则创建一个默认的管理员用户
     */
    private void initAdminUser() {
        String adminUsername = "admin";
        
        // 检查是否已存在admin用户
        User existingAdmin = userService.getByUsername(adminUsername);
        if (existingAdmin != null) {
            logger.info("系统已存在管理员用户: {}", adminUsername);
            return;
        }
        
        // 创建新的管理员用户
        User adminUser = new User();
        adminUser.setUsername(adminUsername);
        // 设置密码为admin123并加密
        adminUser.setPassword(passwordEncoder.encode("admin123"));
        adminUser.setRealName("系统管理员");
        adminUser.setPhone("13800138000");
        adminUser.setEmail("admin@example.com");
        adminUser.setRole(Constants.Role.ADMIN);
        adminUser.setStatus(1); // 启用状态
        adminUser.setCreateTime(LocalDateTime.now());
        adminUser.setUpdateTime(LocalDateTime.now());
        
        // 保存管理员用户
        boolean saved = userService.save(adminUser);
        if (saved) {
            logger.info("成功创建管理员用户: {}", adminUsername);
        } else {
            logger.error("创建管理员用户失败: {}", adminUsername);
        }
    }
    
    /**
     * 为管理员角色分配所有菜单权限
     */
    private void assignAllMenusToAdminRole() {
        // 查询管理员角色
        List<Role> roles = roleService.getAllRoles();
        Role adminRole = null;
        for (Role role : roles) {
            if (Constants.Role.ADMIN.equals(role.getRoleCode())) {
                adminRole = role;
                break;
            }
        }
        
        if (adminRole == null) {
            logger.error("未找到管理员角色");
            return;
        }
        
        // 查询所有菜单
        List<Menu> allMenus = menuService.getAllMenus();
        if (allMenus.isEmpty()) {
            logger.info("系统中暂无菜单，无需分配权限");
            return;
        }
        
        // 获取管理员角色已拥有的菜单ID
        List<Long> existingMenuIds = roleMenuService.getMenuIdsByRoleId(adminRole.getId());
        
        // 如果管理员角色已经拥有所有菜单权限，则无需操作
        if (existingMenuIds.size() == allMenus.size()) {
            logger.info("管理员角色已拥有所有菜单权限");
            return;
        }
        
        // 准备所有菜单ID列表
        List<Long> allMenuIds = new ArrayList<>();
        for (Menu menu : allMenus) {
            allMenuIds.add(menu.getId());
        }
        
        // 为管理员角色分配所有菜单权限
        boolean success = roleMenuService.assignMenusToRole(adminRole.getId(), allMenuIds);
        if (success) {
            logger.info("成功为管理员角色分配所有菜单权限");
        } else {
            logger.error("为管理员角色分配菜单权限失败");
        }
    }
}